package com.itranswarp.learnjava;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
// 当 Spring 创建 AppService 实例时，它会处理所有带有 @Value 注解的字段。
// 如果 @Value 注解的值是一个字符串，Spring 会尝试解析它。
// 如果 @Value 注解的值是一个资源路径，Spring 会尝试加载该资源。
// 如果 @Value 注解的值是一个配置文件中的属性，Spring 会尝试从配置文件中读取该属性。
// 如果 @Value 注解的值是一个环境变量，Spring 会尝试从环境变量中读取该变量。
// 如果 @Value 注解的值是一个系统属性，Spring 会尝试从系统属性中读取该属性。
// 如果 @Value 注解的值是一个表达式，Spring 会尝试解析该表达式。

@Component
public class AppService {

    @Value("1")
    private int version;
    // @Value 可以从配置文件中读取属性值，也可以从资源文件中读取属性值。

    @Value("classpath:/logo.txt")
    private Resource resource;

    // 其实appConfig.logo是不存在的 但是在init方法中this.logo给他赋值了才会有值
    // 当 Spring 看到 ${...} 这样的占位符语法时，
    //它会去 Spring 的环境配置中查找一个名为 app.logo 的属性。
    //它会搜索所有已加载的属性源，比如通过 @PropertySource("app.properties") 加载的
    // app.properties 文件。
    @Value("${app.logo}")
    private String logo;

    @Value("1112")
    private String appServiceInfo;

    String logo2;
    // PostConstruct 表示在Bean创建完毕后，自动调用该方法。
    @PostConstruct
    public void init() throws IOException {
        System.out.println("init AppService..." + resource);
        System.out.println("init AppService...version" + version);
        System.out.println("init AppService...logo" + logo);

        try (var reader = new BufferedReader(
                new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) {
            this.logo2 = reader.lines().collect(Collectors.joining("\n"));
        }
    }

    public void printLogo() {
        System.out.println(logo);
        System.out.println("app.version: " + version);
    }

    public String getLogo() {
        return logo;
    }

    // @Value 可以从配置文件中读取属性值，也可以从资源文件中读取属性值。 必须用getter方法才能读取到属性值。
    // 其他的组件才能用 @Value(#appService.appServiceInfo) 注解读取到。
    // 一般appService这个是bean的名字，如果没有自定义名字，及时类名的首字母变为小写
    public String getAppServiceInfo() {
        return appServiceInfo;
    }
}
